import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException
} from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { AuthService } from '../auth.service'
import { LoginService } from 'src/modules/api-modules/login/login.service'

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private authService: AuthService,
    private reflector: Reflector,
    private loginService?: LoginService
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
      context.getHandler(),
      context.getClass()
    ])

    if (isPublic) return true

    const request = context.switchToHttp().getRequest()
    const token = AuthService.extractTokenFromHeader(request)

    if (!token) {
      throw new UnauthorizedException('请在登陆后重试')
    }

    if (this.loginService && this.loginService.isTokenInvalidated(token)) {
      throw new UnauthorizedException('令牌已失效，请重新登录')
    }

    try {
      const payload = await this.authService.verifyToken(token)
      // 将用户信息附加到请求对象上，以便在控制器中使用
      request['user'] = payload
    } catch (error) {
      throw new UnauthorizedException('请重新登录')
    }

    return true
  }
}
